﻿using System.IO;
using System.Linq;
using dnlib.DotNet;
using NETDeob.Core.Engine;
using NETDeob.Core.Identification;
using System;
using System.Collections.Generic;
using NETDeob.Core.Identification.Obfuscators.Confuser;

// ReSharper disable AssignNullToNotNullAttribute

namespace NETDeob.Core
{
    public class Deobfuscator
    {
        private readonly List<IProtection> Protections = new List<IProtection>
        {
            new Confuser17(),
            new Confuser19()
        };

        public void Deobfuscate()
        {
            // Detection
            foreach (var protection in Protections.Where(protection => protection.Identify(Settings.Target)))
            {
                // Set Settings
                Settings.Protection = protection;
                Settings.TargetAssemblyDef = ModuleDefMD.Load(Settings.Target).Assembly;

                // Output
                Logger.Log(String.Concat("Protection Identified:", Settings.Protection.Name), 0);

                // Start Routines
                foreach (var routine in Settings.Protection.Routines)
                {
                    Logger.Log(String.Concat("\n" ,"Performing Routine:", routine.Description), 0);

                    foreach (var phase in routine.Phases)
                    {
                        Logger.Addition(String.Concat("Performing Phase:", phase.Value), 1);

                        // Check Output
                        if (phase.Key())
                            Logger.Addition(" - Completed \n", 1);
                        else
                        {
                            Logger.Addition(" - Failed \n", 1);
                            Logger.Log("Aborting Routine!", 1);
                            break;
                        }
                    }
                }

                Settings.TargetAssemblyDef.Write(
                    Path.Combine(
                        Path.GetDirectoryName(Settings.Target),
                        String.Concat(Settings.TargetAssemblyDef.Name, "_deob.exe")
                        ));
            }
        }
    }
}